package com.xzh.wms.mybatisx;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import cn.xzh.smart.core.util.UserSessionContext;
import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
import net.sf.jsqlparser.statement.insert.Insert;
import net.sf.jsqlparser.statement.update.Update;
import net.sf.jsqlparser.statement.update.UpdateSet;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;


import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Component
@Intercepts({
        @Signature(type = StatementHandler.class, method = "update", args = {Statement.class})
})
@Slf4j
public class StatementHandlerPlugin implements Interceptor {

    @Autowired
    private MonitorProperties monitorProperties;
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        StatementHandler statement=(StatementHandler)invocation.getTarget();
        BoundSql boundSql = statement.getBoundSql();
        String sql = boundSql.getSql();

        net.sf.jsqlparser.statement.Statement parse = CCJSqlParserUtil.parse(sql);
        if (parse instanceof Insert){
            Insert insert=(Insert)parse;
            InsertHandler(insert);

        } else if (parse instanceof Update) {
            Update update=(Update)parse;
            UpdateHandler(update);
        }
        return invocation.proceed();
    }

    private static final String DingDingUrl="https://oapi.dingtalk.com/robot/send?access_token=a11501e83032b7b7ddc82fe36bca6bfc8815d85a75982b2943c195b7fdc9f102";

    private void sentDingDing(String name){
        JSONObject json1= JSONUtil.createObj();
        json1.putOpt("msgtype","text");
        String format = StrUtil.format("警ni告：{}修改了{}", UserSessionContext.get().getNickName(), name);
        json1.putOpt("text",JSONUtil.createObj().putOpt("content",format));
        json1.putOpt("isAtAll",false);
        JSONArray array = JSONUtil.createArray();
        array.add("1879051053");
        json1.putOpt("atMobiles",array);

        String json = JSONUtil.toJsonStr(json1);
        String result2 = HttpRequest.post(DingDingUrl)
                .body(json)
                .execute().body();

        JSONObject jsonObject = JSONUtil.parseObj(result2);
        Object errcode = jsonObject.get("errcode");
        if(errcode.equals(0)){
            log.debug("发送钉钉成功");
        }else{
            log.error("发送钉钉失败：{}",jsonObject.get("errmsg"));
        }
    }


    private void InsertHandler(Insert insert){
        String name = insert.getTable().getName();
        List<Map<String, List<String>>> tables = monitorProperties.getTables();
        for (Map<String,List<String>> map:tables){
            boolean b = map.keySet().contains(name);
            if (b){
                log.info("警告");
                sentDingDing(name);
                break;
            }
        }
    }

    private void UpdateHandler(Update update){
        String name = update.getTable().getName();
        List<Map<String, List<String>>> tables = monitorProperties.getTables();

        for (Map<String,List<String>> map:tables){
            List<String> monitorColumns = map.get(name);
            if (ObjectUtil.isNotEmpty(monitorColumns)){
                ArrayList<UpdateSet> updateSets = update.getUpdateSets();
                for (UpdateSet item:updateSets){
                    boolean b = monitorColumns.contains(item.getColumns().get(0).getColumnName());
                    if (b){
                        log.info("警告");
                        sentDingDing(name);
                        break;
                    }
                }
            }
        }
    }
}